package mypi;

import java.math.BigDecimal;
import java.math.BigInteger;

import result.Result;
import tasks.Task;

public class PiTask extends Task {


	private static final int ROUND_MODE = BigDecimal.ROUND_HALF_EVEN;
	private BigDecimal ZERO = new BigDecimal("0");
	private BigDecimal ONE = new BigDecimal("1");
	private BigDecimal NEGATIVE_ONE = new BigDecimal("-1");
	private BigDecimal TWO  = new BigDecimal("2");
	private BigDecimal NEGATIVE_TWO = new BigDecimal("-2");
	private BigDecimal FOUR = new BigDecimal("4");
	private BigDecimal FIVE = new BigDecimal("5");
	private BigDecimal SIX = new BigDecimal("6");
	private BigDecimal EIGHT = new BigDecimal("8");
	private BigDecimal NEGATIVE_EIGHT = new BigDecimal("-8");
	private BigInteger SIXTEEN = new BigInteger("16");
	private MyResult result;
	private int start;
	private int end;
	int scale;

	public PiTask(int id, int start, int end, int scale) {
		super(id);
		this.start = start;
		this.end = end;
		this.scale = scale;

	}
	private BigDecimal f(int k) {
		BigDecimal K = new BigDecimal(k);
		BigDecimal EIGHT_K = EIGHT.multiply(K);
		BigDecimal FIRST = ONE.divide(new BigDecimal(SIXTEEN.pow(k)), ROUND_MODE);
		BigDecimal SECOND = FOUR.divide(EIGHT_K.add(ONE), ROUND_MODE);
		BigDecimal THIRD = NEGATIVE_TWO.divide(EIGHT_K.add(FOUR), ROUND_MODE);
		BigDecimal FOURTH = NEGATIVE_ONE.divide(EIGHT_K.add(FIVE), ROUND_MODE);
		BigDecimal FIFTH = NEGATIVE_ONE.divide(EIGHT_K.add(SIX), ROUND_MODE);

		return FIRST.multiply(SECOND.add(THIRD.add(FOURTH.add(FIFTH))));
	}

	public void setScale(Integer scale) {
		ZERO = ZERO.setScale(scale);
		ONE = ONE.setScale(scale);
		NEGATIVE_ONE = NEGATIVE_ONE.setScale(scale);
		TWO = TWO.setScale(scale);
		NEGATIVE_TWO = NEGATIVE_TWO.setScale(scale);
		FOUR = FOUR.setScale(scale);
		FIVE = FIVE.setScale(scale);
		SIX = SIX.setScale(scale);
		EIGHT = EIGHT.setScale(scale);
		NEGATIVE_EIGHT = NEGATIVE_EIGHT.setScale(scale);
	}
	private BigDecimal s(){
		BigDecimal bd = ZERO;
		BigDecimal total = ZERO;
		for (int i = start ;i<end;i++){
			bd = bd.add(f(i));


		}


		return bd;
	}

	@Override
	public void run() {

		setScale(new Integer(scale));

		result = new MyResult(s());

	}


	@Override
	public Result getResult() {
		return result;
	}
	@Override
	public String toString() {
		return "Simple PI Task :)";
	}
	@Override
	public void cancel() {
		Thread.currentThread().interrupt();

	}


}
